﻿#if UNITY_EDITOR
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;

// DYNAMIC ENUM CREATOR
public class SaveDataTools : UnityEditor.AssetModificationProcessor   
{
	[System.Serializable]
	public class EnumData
	{
		public int id;
		public string name;
	}
	
	// This is called by Unity when it is about to write serialized assets or scene files to disk.
	static string[] OnWillSaveAssets(string[] paths) 
	{
		// Blah!
		foreach (string file in paths)
		{
			if ( file.Contains( "GamesManager.prefab" ))
			{
				RewriteEnum();
				break;
			}
		}
		
		return paths;
	}
	
	private static void RewriteEnum()
	{
		string enumFilename = Application.dataPath + "/Core Scripts/Managers/SaveGame/SaveDataID.cs";

		List<string> allAttributesName = new List<string>();
		
		for(int i = 0; i < SaveInfo.Instance.m_AllSaveInfo.Length; i++)
		{
			if(!string.IsNullOrEmpty(SaveInfo.Instance.m_AllSaveInfo[i].m_AttributeName))
			{
				allAttributesName.Add (SaveInfo.Instance.m_AllSaveInfo[i].m_AttributeName );
			}
		}

		CreateEnumFrom( allAttributesName, "AttributeID", typeof(SaveDataID.AttributeID), enumFilename );
	}
	
	// Merge the old enum with the new one
	private static List<EnumData> MergeEnumWithList( List<string> i_List, System.Type i_EnumType, ref int i_LastIndex ) 
	{
		List<EnumData> enumList = new List<EnumData>();
		
		foreach ( string element in i_List )
		{
			EnumData data = new EnumData();
			data.id   = -1;
			data.name = element;
			
			if ( System.Enum.IsDefined( i_EnumType, element ) )
			{
				data.id = (int)System.Enum.Parse( i_EnumType, element );
				if ( data.id > i_LastIndex )
				{
					i_LastIndex = data.id;
				}
			}
			else
			{
				data.id  = -1;
			}
			
			enumList.Add(data);
		}
		
		return enumList;
	}
	
	// Transform a List<string> to a Enum
	private static bool CreateEnumFrom( List<string> i_List, string i_EnumName, System.Type i_EnumType, string i_EnumFilename )
	{
		if( System.IO.File.Exists( i_EnumFilename ) == false )
		{
			return false;
		}
		
		int lastEnumId = 0;
		List<EnumData> mergedEnumData = MergeEnumWithList( i_List, i_EnumType, ref lastEnumId );
				

		//string oTextFile = System.IO.File.ReadAllText( i_EnumFilename );
		string oTextFile = "";
		string startEnumText = "public enum " + i_EnumName;
		string endEnumText   = "};";
		
		int startEnumIndex = oTextFile.IndexOf( startEnumText );
		if( startEnumIndex >= 0 )
		{
			int endEnumIndex = oTextFile.IndexOf( endEnumText, startEnumIndex, System.StringComparison.CurrentCultureIgnoreCase );
			
			int startEnumAt = startEnumIndex + startEnumText.Length;
			int endEnumAt   = endEnumIndex + endEnumText.Length;
			
			int enumLenght =  Mathf.Clamp( endEnumAt - startEnumAt, 0, int.MaxValue );
			oTextFile = oTextFile.Remove( startEnumAt, enumLenght );
			
			#if UNITY_EDITOR_WIN
			string oNewLineControl = "\r\n";
			#else
			string oNewLineControl = "\n";
			#endif
			
			string newEnumText = oNewLineControl + "\t{" + oNewLineControl;
			
			for ( int i = 0 ; i < mergedEnumData.Count ; ++i )
			{
				// Check if enum is not already defined
				bool bFound = false;
				
				for( int iCmpt = 0; iCmpt < i; iCmpt++ )
				{
					if( mergedEnumData[i].name == mergedEnumData[iCmpt].name )
					{
						bFound = true;
						break;
					}
				}
				
				if( !bFound )
				{
					if ( mergedEnumData[i].id == -1 ) mergedEnumData[i].id = ++lastEnumId;
					newEnumText += "\t\t" + mergedEnumData[i].name + "\t= " + mergedEnumData[i].id + "," + oNewLineControl;
				}
			}
			
			newEnumText += oNewLineControl + "\t\tNONE\t= 1000" + oNewLineControl;
			newEnumText += "\t};";

			oTextFile = oTextFile.Insert( startEnumAt, newEnumText );
			
			//System.IO.File.WriteAllText( i_EnumFilename, oTextFile );
			
			return true;
		}
		
		return false;
	}
}

#endif
